<?php
// 接口-inventoryDefaultClass
namespace interface\v1;

class inventoryDefaultClass extends index
{
	/**
	 * 成本与利润
	 */
	public static function costProfit($type, $date = null)
	{
		//毛利润
		$where = " and a.coid = '" . self::$coid . "' and b.state = '已确认'";
		if ($date) {
			$where .= self::timeComparison($date, 'date', 'b.recordDate');
		}
		$income       = 0;
		$freightMoney = 0;
		$cost         = 0;
		$result       = sqlFind(" select a.id from sale_order_detail as a join sale_order as b on a.orderId = b.id where 1=1 $where order by a.time desc ");
		if (is_array($result)) {
			foreach ($result as $array) {
				//发货出库数量
				$out_num = find(array('table' => 'inventory_detail', 'where' => "sourceId in (select id from sale_send_order_detail where saleOrderMxId = '$array[id]')", 'sum' => "num"));
				//退货入库数量
				$in_num = find(array('table' => 'inventory_detail', 'where' => "sourceId in (select id from sale_refund_order_detail where sourceId = '$array[id]')", 'sum' => "num"));
				//出库金额
				$out_Money = find(array('table' => 'inventory_detail', 'where' => "sourceId in (select id from sale_send_order_detail where saleOrderMxId = '$array[id]')", 'sum' => "money"));
				//退货金额
				$refund_Money = find(array('table' => 'inventory_detail', 'where' => "sourceId in (select id from sale_refund_order_detail where sourceId = '$array[id]')", 'sum' => "money"));
				//分摊运费
				$freightMoney += find(array('table' => 'sale_send_order_loading', 'where' => "saleOrderMxId = '$array[id]'", 'sum' => 'freight'));

				$income += round($out_Money - $refund_Money, 2);
				$cost   += self::cost($array['id'], $out_num - $in_num);
			}
		}
		$grossProfit = round($income - $cost - $freightMoney, 2);
		//毛利率
		$grossProfitRate = ($income > 0 ? round((($income - $cost - $freightMoney) / $income) * 100, 1) : 0);
		$money           = match ($type) {
			'销售成本' => $cost,
			'毛利润'   => $grossProfit,
			'毛利率'   => $grossProfitRate,
		};
		return $money;
	}

	/**
	 * 销售成本
	 */
	public static function cost($saleOrderMxId, $saleNum, $round = true): float
	{
		$saleOrderMx = query('sale_order_detail', "id = '$saleOrderMxId'");
		$saleOrder   = query('sale_order', "id = '$saleOrderMx[orderId]'");
		$price       = self::getInventoryPrice($saleOrderMx['materialId'], time: $saleOrder['recordDate']);
		return $saleOrderMx['id'] ? (($round === true) ? round($price * $saleNum, 2) : $price * $saleNum) : 0;
	}

	/**
	 * 获取库存均价
	 *
	 * @param        $materialId
	 * @param string $unit
	 * @param string $time
	 * @return int|float
	 */
	public static function getInventoryPrice($materialId, string $unit = '', string $time = ''): int|float
	{
		$material = query('material', " id = '" . $materialId . "' ");
		$where    = '';
		if ($time) {
			//带时分秒格式
			$where .= " and UNIX_TIMESTAMP(recordTime) <= UNIX_TIMESTAMP('" . $time . "')";
			if (date('Y-m-d', strtotime($time)) == $time) {
				//日期格式  取日期当前最早一条，如果没有，则取小于当天的最新一条
				$inventory_price = query("inventory_price", " coid = '" . self::$coid . "' and materialId = '" . $materialId . "' and date_format(recordTime,'%Y-%m-%d')='$time' order by id asc ");
				if ($inventory_price['id']) {
					$price = (float)$inventory_price['avgPrice'] ?: 0;
					return $unit ? self::material_num_change($materialId, $unit, $material['unit']) * $price : $price;
				}
			}
		}
		$inventory_price = query("inventory_price", " coid = '" . self::$coid . "' and materialId = '" . $materialId . "' $where order by id desc ", 'avgPrice');
		$price           = (float)$inventory_price['avgPrice'] ?: 0;
		return $unit ? self::material_num_change($materialId, $unit, $material['unit']) * $price : $price;
	}

	/**
	 * 物料单位转换
	 *
	 * @param     $materialId
	 * @param     $from
	 * @param     $to
	 * @param int $num
	 * @return int|float
	 */
	public static function material_num_change($materialId, $from, $to, int $num = 1): int|float
	{
		$num = $num ?: 0;
		if ($from == $to) {
			return $num;
		}
		$material               = query('material', " id = '$materialId'");
		if ($from == $material['unit_one']) {
			$num = $material['unit_one_num'] * $num;
		} elseif ($from == $material['unit_two']) {
			$num = $material['unit_two_num'] * $num;
		}
		if ($to == $material['unit_one']) {
			$num = $material['unit_one_num'] > 0 ? round($num / $material['unit_one_num'], 2) : 0;
		} elseif ($to == $material['unit_two']) {
			$num = $material['unit_two_num'] > 0 ? round($num / $material['unit_two_num'], 2) : 0;
		}
		return $num;
	}

	/**
	 * 供应商按期交货率
	 */
	public static function deliveryRate($type, $date = '')
	{
		$where = '';
		if ($date) {
			$where .= self::timeComparison($date, 'date', 'recordDate');
		}
		//按期交货率
		$orderNum             = find([
			'table'  => "purchase_order",
			'field'  => "IFNULL(count(id),0) as num",
			'single' => " coid = '" . self::$coid . "' and state = '已确认' " . $where,
		])['num'] ?? 0;
		$onScheduleNum        = find([
			'table'  => "purchase_order",
			'field'  => "IFNULL(count(id),0) as num",
			'single' => " coid = '" . self::$coid . "' and state = '已确认' and actual_delivery_date is not null and deliveryDate >= actual_delivery_date " . $where,
		])['num'] ?? 0;
		$delayNum             = find([
			'table'  => "purchase_order",
			'field'  => "IFNULL(count(id),0) as num",
			'single' => " coid = '" . self::$coid . "' and state = '已确认' and actual_delivery_date is not null and deliveryDate < actual_delivery_date " . $where,
		])['num'] ?? 0;
		$scheduleDeliveryRate = ($orderNum > 0 ? round(($onScheduleNum / $orderNum) * 100, 1) : 0);

		return match ($type) {
			'按期交货订单笔数' => $onScheduleNum,
			'延期交货订单笔数' => $delayNum,
			'按期交货率'       => $scheduleDeliveryRate > 0 ? $scheduleDeliveryRate . '%' : $scheduleDeliveryRate,
		};
	}
}

